/*
  请求模块
 */
import axios from 'axios';
import JSONbig from 'json-bigint';
import {
  Toast
} from 'vant';

//这里加载store和在组件中this.$store是一种东西
import store from '@/store/';
import router from '@/router/';

const refreshTokenReq = axios.create({
  baseURL: 'http://toutiao-app.itheima.net/',
})

const request = axios.create({
  baseURL: 'http://toutiao-app.itheima.net/', //基础路径
  transformResponse: [function (data) {

    //后端返回的数据可能不是JSON格式字符串，那么JSONbig.parse调用就会报错,所以要捕获异常处理 

    try {
      return JSONbig.parse(data)
    } catch (err) {
      console.log('转换失败', err);
      //转换失败，把数据原封不动的直接返回给请求使用
      return data
    }
    //axios默认在内部使用JSON.parse来转换处理原始数据
    //return JSON.parse(data)
  }]
})
request.defaults.headers.post['Content-Type'] = 'application/json';


//请求拦截器
request.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  const {
    user
  } = store.state

  //如果用户已登录，统一给接口设置token信息
  if (user) {
    config.headers.Authorization = `Bearer ${user.token}`
  }

  //处理完之后一定要返回，否则请求会停在这里
  return config;
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error);
});

//响应拦截器
request.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  return response;
}, async function (error) {
  // 对响应错误做点什么
  const status = error.response.status
  if (status === 400) {
    //客户端错误
    Toast.fail('客户端请求参数异常')
  } else if (status === 401) {
    //token 无效
    //如果没有user或者user.token，直接去登陆
    const {
      user
    } = store.state
    if (!user || !user.token) {
      //跳转到登录页
      return redirectLogin()
    }

    //使用 refresh_token 请求获取新的 token
    try {
      const {
        data
      } = await refreshTokenReq({
        method: 'PUT',
        url: '/v1_0/authorizations',
        header: {
          Authorization: `Bearer ${user.refresh_token}`
        }
      })

      //拿到新的token之后把它跟信道容器中
      user.token = data.data.token
      store.commit('setUser', user)

      //把失败的请求重新发出去
      //error.config是本次请求的相关配置信息对象
      //这里使用request发请求，它会走自己的拦截器
      //它的请求拦截器中通过 store 容器访问 token 数据
      return request(error.config)
    } catch (err) {
      //刷新token都失败，直接跳转登录页
      redirectLogin()
    }
  } else if (status === 401) {
    //没有权限操作
    Toast.fail('没有权限操作')
  } else if (status >= 500) {
    //服务端异常
    Toast.fail('服务端异常，请稍后重试')
  }
  return Promise.reject(error);
});

function redirectLogin() {
  router.replace({
    name: 'login',
    //传递查询参数，查询参数会以 ？ 作为分隔符放到url后面
    query: {
      //数据名是自己起的
      //router.currentRoute和我们组件中获取的this.$route是一个东西
      redirect: router.currentRoute.fullPath
    }
  })
}

//导出
export default request